﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace BreadScrapeWorkerRole
{
    public class Util
    {
        public static string GetDateUrl(DateTime date)
        {
            StringBuilder key = new StringBuilder(date.Year.ToString(), 20);
            key.Append('/');
            if (date.Month < 10)
                key.Append('0');
            key.Append(date.Month);
            key.Append('/');
            if (date.Day < 10)
                key.Append('0');
            key.Append(date.Day);
            return key.ToString();
        }

        public static string StripHTML(string source)
        {
            try
            {
                string result;

                // Remove HTML Development formatting
                // Replace line breaks with space
                // because browsers inserts space
                result = source.Replace("\r", " ");
                // Replace line breaks with space
                // because browsers inserts space
                result = result.Replace("\n", " ");
                // Remove step-formatting
                result = result.Replace("\t", string.Empty);
                // Remove repeating spaces because browsers ignore them
                result = System.Text.RegularExpressions.Regex.Replace(result,
                                                                      @"( )+", " ");

                // Remove the header (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*head([^>])*>", "<head>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*head( )*>)", "</head>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(<head>).*(</head>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);


                // remove all scripts (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*script([^>])*>", "<script>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*script( )*>)", "</script>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                //result = System.Text.RegularExpressions.Regex.Replace(result,
                //         @"(<script>)([^(<script>\.</script>)])*(</script>)",
                //         string.Empty,
                //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<script>).*(</script>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // remove all styles (prepare first by clearing attributes)
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*style([^>])*>", "<style>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"(<( )*(/)( )*style( )*>)", "</style>",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(<style>).*(</style>)", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert tabs in spaces of <td> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*td([^>])*>", "\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert line breaks in places of <BR> and <LI> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<br />", "\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*li( )*>", "\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // insert line paragraphs (double line breaks) in place
                // if <P>, <DIV> and <TR> tags
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*div([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*tr([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<( )*p([^>])*>", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // Remove remaining tags like <a>, links, images,
                // comments etc - anything that's enclosed inside < >
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"<[^>]*>", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // replace special characters:
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @" ", " ",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&bull;", " * ",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&lsaquo;", "'",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&rsaquo;", "'",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&trade;", "(tm)",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&frasl;", "/",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&lt;", "<",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&gt;", ">",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&copy;", "(c)",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&reg;", "(r)",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Remove all others. More can be added, see
                // http://hotwired.lycos.com/webmonkey/reference/special_characters/
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         @"&(.{2,6});", string.Empty,
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // for testing
                //System.Text.RegularExpressions.Regex.Replace(result,
                //       this.txtRegex.Text,string.Empty,
                //       System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // make line breaking consistent
                result = result.Replace("\n", "\r");

                // Remove extra line breaks and tabs:
                // replace over 2 breaks with 2 and over 4 tabs with 4.
                // Prepare first to remove any whitespaces in between
                // the escaped characters and remove redundant tabs in between line breaks
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)( )+(\r)", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\t)( )+(\t)", "\t\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\t)( )+(\r)", "\t\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)( )+(\t)", "\r\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Remove redundant tabs
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)(\t)+(\r)", "\r\r",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Remove multiple tabs following a line break with just one tab
                result = System.Text.RegularExpressions.Regex.Replace(result,
                         "(\r)(\t)+", "\r\t",
                         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                // Initial replacement target string for line breaks
                //string breaks = "\r\r\r";
                //// Initial replacement target string for tabs
                //string tabs = "\t\t\t\t\t";
                //for (int index = 0; index < result.Length; index++)
                //{
                //    result = result.Replace(breaks, "\r\r");
                //    result = result.Replace(tabs, "\t\t\t\t");
                //    breaks = breaks + "\r";
                //    tabs = tabs + "\t";
                //}

                // strip leading spaces
                result = System.Text.RegularExpressions.Regex.Replace(result,
                            @"^\s+", String.Empty,
                            System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                // That's it.
                return result;
            }
            catch
            {
                //MessageBox.Show("Error");
                return source;
            }
        }

        public static string ExtractVerseUrl(string getResults)
        {
            // retrieve the bible verse
            int startIndex = getResults.IndexOf("passage-box");
            int hrefStartIndex = getResults.IndexOf("href=", startIndex) + 6;
            int hrefEndIndex = getResults.IndexOf("\"", hrefStartIndex);
            string url = getResults.Substring(hrefStartIndex, hrefEndIndex - hrefStartIndex); // + "&version=NKJV";
            return url;
        }

        public static string ConstructVerseUrl(string verseName)
        {
            StringBuilder sb = new StringBuilder("http://www.biblegateway.com/passage/?search=");
            sb.Append(System.Web.HttpUtility.UrlEncode(verseName));
            //sb.Append("&version=NKJV");
            return sb.ToString();
        }

        public static void ExtractContent(ref ContentEntity context, string getResults)
        {
            // get the title of the daily bread
            int startIndex = getResults.IndexOf("entry-thumbnail");
            startIndex = getResults.IndexOf("title=", startIndex) + 7;
            int endIndex = getResults.IndexOf("\"", startIndex);
            context.BreadName = getResults.Substring(startIndex, endIndex - startIndex); // "You had to act"

            // get the ref bible text
            startIndex = getResults.IndexOf("passage-box");
            int refBibleStart = getResults.IndexOf("Scripture Passage\">", startIndex) + 19;
            int refBibleEnd = getResults.IndexOf("</a>", refBibleStart);
            context.VerseName = getResults.Substring(refBibleStart, refBibleEnd - refBibleStart);// "John 3:7-16"

            // get the bread main content
            startIndex = getResults.IndexOf("post-content") + 15;
            endIndex = getResults.IndexOf("<div class=\"entry-meta-box\">");
            string content = getResults.Substring(startIndex, endIndex - startIndex);
            content = HttpUtility.HtmlDecode(content);
            content = Util.StripHTML(content);

            // Get the short verse 
            int articleverseStartingPos = getResults.IndexOf("verse-box") + 11;
            int articleverseEndPos = getResults.IndexOf("</div>", articleverseStartingPos);
            string verse = getResults.Substring(articleverseStartingPos, articleverseEndPos - articleverseStartingPos);
            verse = Util.StripHTML(verse);
            context.ArticleVerse = verse;

            context.BreadContent = context.currentDate.ToLongDateString()
                                            + "\n\n"
                                            + context.ArticleVerse
                                            + "\n\n"
                                            + content;
            return;
        }

        public static string ExtractVerseContent(string refBibleResults)
        {
            StringBuilder refBibleVerse = new StringBuilder("<html><body>");
            int refStartIndex = refBibleResults.IndexOf("<span id=\"en-NIV");
            int refEndIndex = refBibleResults.IndexOf("<div class=\"publisher-info-bottom", refStartIndex);
            refBibleVerse.Append(refBibleResults.Substring(refStartIndex, refEndIndex - refStartIndex));
            refBibleVerse.Append("</body></html>");
            refBibleResults = refBibleResults.Substring(refStartIndex, refEndIndex - refStartIndex);

            //strip the footnote reference
            refStartIndex = refBibleResults.IndexOf("<sup data-fn");
            while (refStartIndex != -1)
            {
                refEndIndex = refBibleResults.IndexOf("</sup>", refStartIndex);
                refBibleResults = refBibleResults.Remove(refStartIndex, refEndIndex - refStartIndex + 6);
                refStartIndex = refBibleResults.IndexOf("<sup data-fn");
            }

            //strip the cross reference
            refStartIndex = refBibleResults.IndexOf("<sup class='crossreference'");
            while (refStartIndex != -1)
            {
                refEndIndex = refBibleResults.IndexOf("</sup>", refStartIndex);
                refBibleResults = refBibleResults.Remove(refStartIndex, refEndIndex - refStartIndex + 6);
                refStartIndex = refBibleResults.IndexOf("<sup class='crossreference'");
            }

            return StripHTML(refBibleResults);
        }

    }
}